#include "StdAfx.h"
#include "ItemSizeManager.h"

CItemSizeManager::CItemSizeManager(void)
{
	m_ItemLinkHead.pNext = NULL;
}

CItemSizeManager::~CItemSizeManager(void)
{
	try
	{
		LP_ITEM_LINEK_NODE pItem = m_ItemLinkHead.pNext;
		m_ItemLinkHead.pNext = NULL;
		while(pItem != NULL)
		{
			LP_ITEM_LINEK_NODE pNextItem = pItem->pNext;
			delete pItem;
			pItem = pNextItem;
		}
	}
	catch(...)
	{
	}
}

// Add Item and it's resize style that need processed by this class
BOOL CItemSizeManager::AddItem(UINT ItemId, DWORD dwAnchor)
{
	LP_ITEM_LINEK_NODE pNode = new ITEM_LINEK_NODE;
	if (pNode == NULL)
	{
		return FALSE;
	}

	memset(pNode, 0, sizeof(*pNode));

	pNode->Id = ItemId;
	pNode->Anchor = dwAnchor;
	pNode->pNext = m_ItemLinkHead.pNext;
	m_ItemLinkHead.pNext = pNode;

	return TRUE;
}

// Init item's position information
BOOL CItemSizeManager::Initialize(HWND hWnd)
{
	if (!::IsWindow(hWnd))
	{
		return FALSE;
	}

	// Get container window's client window size;
	RECT ClientRect;
	if (!::GetClientRect(hWnd, &ClientRect))
	{
		return FALSE;
	}
	m_ItemLinkHead.Size.cx = ClientRect.right - ClientRect.left;
	m_ItemLinkHead.Size.cy = ClientRect.bottom - ClientRect.top;

	// Get item's position information
	LP_ITEM_LINEK_NODE pItem = m_ItemLinkHead.pNext;
	while(pItem != NULL)
	{
		HWND hItem = ::GetDlgItem(hWnd, pItem->Id);
		if (hItem != NULL)
		{
			RECT ItemRect;
			if (::GetWindowRect(hItem, &ItemRect))
			{
				if (ScreenToClientRect(hWnd, ItemRect))
				{
					pItem->LeftTop.x = ItemRect.left;
					pItem->LeftTop.y = ItemRect.top;
					pItem->Size.cx = ItemRect.right - ItemRect.left;
					pItem->Size.cy = ItemRect.bottom - ItemRect.top;
				}
			}
		}

		pItem = pItem->pNext;
	}

	return TRUE;
}

// UnInitialize
void CItemSizeManager::UnInitialize(void)
{
	try
	{
		LP_ITEM_LINEK_NODE pItem = m_ItemLinkHead.pNext;
		m_ItemLinkHead.pNext = NULL;
		while(pItem != NULL)
		{
			LP_ITEM_LINEK_NODE pNextItem = pItem->pNext;
			delete pItem;
			pItem = pNextItem;
		}
	}
	catch(...)
	{
	}
}

// Converts the screen coordinates of a specified rect on the screen to client-area coordinates. 
BOOL CItemSizeManager::ScreenToClientRect(HWND hWnd, RECT & Rect)
{
	if (!::IsWindow(hWnd))
	{
		return FALSE;
	}

	POINT LeftTop;
	POINT RightBottom;

	memcpy(&LeftTop, &Rect, sizeof(POINT));
	memcpy(&RightBottom, &Rect.right, sizeof(POINT));

	BOOL bLeftTop = ::ScreenToClient(hWnd, &LeftTop);
	BOOL bRightBottom = ::ScreenToClient(hWnd, &RightBottom);

	if (bLeftTop & bRightBottom)
	{
		memcpy(&Rect, &LeftTop, sizeof(POINT));
		memcpy(&Rect.right, &RightBottom, sizeof(POINT));

		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

// Converts the client-area coordinates of a specified point to screen coordinates.
BOOL CItemSizeManager::ClientToScreenRect(HWND hWnd, RECT & Rect)
{
	if (!::IsWindow(hWnd))
	{
		return FALSE;
	}

	POINT LeftTop;
	POINT RightBottom;

	memcpy(&LeftTop, &Rect, sizeof(POINT));
	memcpy(&RightBottom, &Rect.right, sizeof(POINT));

	BOOL bLeftTop = ::ClientToScreen(hWnd, &LeftTop);
	BOOL bRightBottom = ::ClientToScreen(hWnd, &RightBottom);

	if (bLeftTop & bRightBottom)
	{
		memcpy(&Rect, &LeftTop, sizeof(POINT));
		memcpy(&Rect.right, &RightBottom, sizeof(POINT));

		return TRUE;
	}
	else
	{
		return FALSE;
	}
}

// Resize items when container window's size is changed
void CItemSizeManager::OnSize(HWND hWnd, SIZE &WndSize)
{
	if (!::IsWindow(hWnd))
	{
		return ;
	}

	// Get container window's client window size;
	RECT ClientRect;
	if (!::GetClientRect(hWnd, &ClientRect))
	{
		return ;
	}

	int dx = WndSize.cx - m_ItemLinkHead.Size.cx;
	int dy = WndSize.cy - m_ItemLinkHead.Size.cy;
	m_ItemLinkHead.Size.cx = WndSize.cx;
	m_ItemLinkHead.Size.cy = WndSize.cy;
	if ((dx == 0) && (dy == 0))
	{
		return;
	}

	// Get item's position information
	LP_ITEM_LINEK_NODE pItem = m_ItemLinkHead.pNext;
	while(pItem != NULL)
	{
		HWND hItem = ::GetDlgItem(hWnd, pItem->Id);
		if (hItem != NULL)
		{
			if (pItem->Anchor & ANCHOR_BOTTOM)
			{
				if (pItem->Anchor & ANCHOR_TOP)
				{
					pItem->Size.cy += dy;
				}
				else
				{
					pItem->LeftTop.y += dy;
				}
			}

			if (pItem->Anchor & ANCHOR_RIGHT)
			{
				if (pItem->Anchor & ANCHOR_LEFT)
				{
					pItem->Size.cx += dx;
				}
				else
				{
					pItem->LeftTop.x += dx;
				}
			}

			::MoveWindow(hItem,
						pItem->LeftTop.x, pItem->LeftTop.y,
						pItem->Size.cx, pItem->Size.cy,
						TRUE);
		}

		pItem = pItem->pNext;
	}
}